package kaang.dev.warpimage;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Random;

import kaang.dev.warpimage.panel.Panel;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.sax.RootElement;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class ImageWarpActivity extends Activity implements
		View.OnClickListener, View.OnTouchListener {

    private static int RESULT_LOAD_IMAGE = 1;
    private static int RESULT_TAKE_PHOTO = 2;

	Panel panelLeft;
	Panel panelRight;
	Panel panelBottom;
	Button btnDraw;
	Button btnSetting;

	Button btnUndo;
	Button btnRight;
	Button btnLeft;
	Button btnMaxi;
	Button btnMini;
	Button btnMove;

	Button btnSizeLow;
	Button btnSizeMed;
	Button btnSizeHig;
	
	Button btnStrenghtLow;
	Button btnStrenghtMed;
	Button btnStrenghtHig;

	Button btnRefresh;
	Button btnSave;
	Button btnLoad;
	Button btnShare;
	Button btnTakePic;
	Button btnTest;

	Handler handler = new Handler();

	public static int ACTION_UNDO = 5;
	public static int ACTION_MAXI = 1;
	public static int ACTION_MINI = 0;
	public static int ACTION_RIGHT = 3;
	public static int ACTION_LEFT = 2;
	public static int ACTION_MOVE = 4;

	public static int STRENGHT_LOW = 0;
	public static int STRENGHT_MED = 1;
	public static int STRENGHT_HIG = 2;

	public static int RANGE_LOW = 0;
	public static int RANGE_MED = 1;
	public static int RANGE_HIG = 2;

	public int curAction = 4;
	public int curStrength;
	public int curRange;
	public Bitmap originbmp;

	TextView textView;
	WarpingMatrix transform;
	int drawingcount = 0;
	int setttingcount = 0;
	ImageView imgView;

	// touch event params
	int pre_X;
	int pre_Y;
	int cur_X;
	int cur_Y;
	boolean isPressing = false;
	long pre_time = 0;
	float eslaspe_time = 0.2f;	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_image_warp);
		init();
	}

	public void init() {
		btnDraw = (Button) findViewById(R.id.draw);
		panelLeft = (Panel) findViewById(R.id.leftPanel1);
		panelBottom = (Panel) findViewById(R.id.bottomPanel1);
		btnSetting = (Button) findViewById(R.id.setting);
		panelRight = (Panel) findViewById(R.id.rightPanel1);
		btnDraw.setOnClickListener(this);
		btnSetting.setOnClickListener(this);
		btnDraw.setOnTouchListener(this);
		btnSetting.setOnTouchListener(this);

		btnUndo = (Button) findViewById(R.id.btnUndo);
		btnUndo.setOnClickListener(this);
		btnLeft = (Button) findViewById(R.id.btnLeft);
		btnLeft.setOnClickListener(this);
		btnRight = (Button) findViewById(R.id.btnRight);
		btnRight.setOnClickListener(this);
		btnMaxi = (Button) findViewById(R.id.btnMaxi);
		btnMaxi.setOnClickListener(this);
		btnMini = (Button) findViewById(R.id.btnMini);
		btnMini.setOnClickListener(this);
		btnMove = (Button) findViewById(R.id.btnMove);
		btnMove.setOnClickListener(this);
		
		btnRefresh = (Button) findViewById(R.id.btnRefresh);
		btnRefresh.setOnClickListener(this);
		btnSave = (Button) findViewById(R.id.btnSave);
		btnSave.setOnClickListener(this);
		btnLoad = (Button) findViewById(R.id.btnLoad);
		btnLoad.setOnClickListener(this);
		btnTakePic = (Button) findViewById(R.id.btnPhoto);
		btnTakePic.setOnClickListener(this);
		
		btnSizeHig = (Button) findViewById(R.id.btnSize1);
		btnSizeHig.setOnClickListener(this);
		btnSizeMed = (Button) findViewById(R.id.btnSize2);
		btnSizeMed.setOnClickListener(this);
		btnSizeLow = (Button) findViewById(R.id.btnSize3);
		btnSizeLow.setOnClickListener(this);

		btnStrenghtHig = (Button) findViewById(R.id.btnForce1);
		btnStrenghtHig.setOnClickListener(this);
		btnStrenghtMed = (Button) findViewById(R.id.btnForce2);
		btnStrenghtMed.setOnClickListener(this);
		btnStrenghtLow = (Button) findViewById(R.id.btnForce3);
		btnStrenghtLow.setOnClickListener(this);


		imgView = (ImageView) findViewById(R.id.imgView);
		imgView.setOnTouchListener(imgSourceOnTouchListener);

		final Bitmap test = BitmapFactory.decodeResource(getResources(),
				R.drawable.darkmagic);
		SetInitialImage(test);
		// Button button = new Button(this);
		// button.setBackgroundResource(R.drawable.size01_on_basic);
		// LayoutParams param = new LayoutParams(LayoutParams.WRAP_CONTENT,
		// LayoutParams.WRAP_CONTENT);
		// button.setLayoutParams(param);
		// LinearLayout layout = (LinearLayout) panelLeft
		// .findViewById(R.id.panelContent);
		// layout.addView(button);
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		
		if (requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK && null != data) {
            Uri selectedImage = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };
 
            Cursor cursor = getContentResolver().query(selectedImage,
                    filePathColumn, null, null, null);
            cursor.moveToFirst();
 
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);
            cursor.close();
             
            SetInitialImage(BitmapFactory.decodeFile(picturePath));
        }
		if (requestCode == RESULT_TAKE_PHOTO && resultCode == RESULT_OK && null != data) {
        }
	}

	public void SetInitialImage(Bitmap bmp)
	{
		int kind = 3;
		int area = 0;
		int intense = 0;
		
		if(transform != null)
		{
			kind = transform.getActive_kindID();
			area = transform.getActive_areaID();
			intense = transform.getActive_intensityID();
		}
		originbmp = bmp.copy(Bitmap.Config.ARGB_8888, true);
		transform = new WarpingMatrix(originbmp.getWidth(), originbmp.getHeight(), kind, area, intense);
		imgView.setImageBitmap(bmp);
	}
	public void onClick(View v) {
		final View view = v;
		switch (v.getId()) {
		case R.id.draw:
			handler.post(new Runnable() {
				public void run() {
					panelLeft.getClickListener().onClick(view);
					panelBottom.getClickListener().onClick(view);
				}
			});
			drawingcount = (drawingcount + 1) % 2;
			if(drawingcount == 0)
				btnDraw.setBackgroundResource(R.drawable.ecset_basic);
			else
				btnDraw.setBackgroundResource(R.drawable.ecset_on_basic);
			break;
		case R.id.setting:
			handler.post(new Runnable() {
				public void run() {
					panelRight.getClickListener().onClick(view);
				}
			});
			setttingcount = (setttingcount + 1) % 2;
			if(setttingcount == 0)
				btnSetting.setBackgroundResource(R.drawable.gears_basic);
			else
				btnSetting.setBackgroundResource(R.drawable.gears_on_basic);			
			break;
		case R.id.btnUndo:
			SetButtonLeftPanelImage(ACTION_UNDO);
			transform.setActive_kindID(ACTION_UNDO);
			break;
		case R.id.btnLeft:
			SetButtonLeftPanelImage(ACTION_LEFT);
			transform.setActive_kindID(ACTION_LEFT);
			break;
		case R.id.btnRight:
			SetButtonLeftPanelImage(ACTION_RIGHT);
			transform.setActive_kindID(ACTION_RIGHT);
			break;
		case R.id.btnMaxi:
			SetButtonLeftPanelImage(ACTION_MAXI);
			transform.setActive_kindID(ACTION_MAXI);
			break;
		case R.id.btnMini:
			SetButtonLeftPanelImage(ACTION_MINI);
			transform.setActive_kindID(ACTION_MINI);
			break;
		case R.id.btnMove:
			SetButtonLeftPanelImage(ACTION_MOVE);
			transform.setActive_kindID(ACTION_MOVE);
			break;
		case R.id.btnSize1:
			SetButtonSizeImage(1);
			transform.setActive_areaID(RANGE_HIG);
			break;
		case R.id.btnSize2:
			SetButtonSizeImage(2);
			transform.setActive_areaID(RANGE_MED);
			break;
		case R.id.btnSize3:
			SetButtonSizeImage(3);
			transform.setActive_areaID(RANGE_LOW);
			break;
		case R.id.btnForce1:
			SetButtonForceImage(1);
			transform.setActive_intensityID(STRENGHT_HIG);
			break;
		case R.id.btnForce2:
			SetButtonForceImage(2);
			transform.setActive_intensityID(STRENGHT_MED);
			break;
		case R.id.btnForce3:
			SetButtonForceImage(3);
			transform.setActive_intensityID(STRENGHT_LOW);
			break;
		case R.id.btnRefresh:
			imgView.setImageBitmap(originbmp);
			break;
		case R.id.btnSave:
			Drawable imgDrawable = imgView.getDrawable();
			Bitmap bitmap = ((BitmapDrawable) imgDrawable).getBitmap();
			if(SaveImage(bitmap) == 1)
			{
				Toast.makeText(getApplicationContext(), "Saved", 1).show();
			}
			
			break;
		case R.id.btnLoad:
			Intent i = new Intent(
			Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);		 
			startActivityForResult(i, RESULT_LOAD_IMAGE);
			break;
		case R.id.btnPhoto:
			//TODO camera stuff.
			Intent openCam = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

			Random r = new Random();
            int roll_ = r.nextInt(10000) + 1;
            String file_name = String.valueOf(roll_) + ".png";
            File photo_out = new File(Environment.getExternalStorageDirectory(), file_name);
            Uri uriSavedImage = Uri.fromFile(photo_out);
            openCam.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage); // set the image file name

			startActivityForResult(openCam, RESULT_TAKE_PHOTO);
			break;
		default:
			break;
		}
		transform.TransformMatrixX();
	}
	
	public int SaveImage(Bitmap bmp)
	{
		Random fCount = new Random();
        int roll = fCount.nextInt(10000) + 1;
        String filename = String.valueOf(roll) + ".png";
        File root = Environment.getExternalStorageDirectory();
		File f = new File(root, filename);
		
		FileOutputStream fout = null;
		try{
			fout = new FileOutputStream(f);
			if(fout != null)
			{
				bmp.compress(Bitmap.CompressFormat.PNG, 90, fout);
				fout.close();
				//wipingSdcard();
			}
		}
		catch (Exception e) {
			// TODO: handle exception
			return 0;
		}
		return 1;
	}
	
	public void wipingSdcard() {
        File deleteMatchingFile = new File(Environment
                .getExternalStorageDirectory().toString());
        try {
            File[] filenames = deleteMatchingFile.listFiles();
            if (filenames != null && filenames.length > 0) {
                for (File tempFile : filenames) {
                    if (tempFile.isDirectory()) {
                        wipeDirectory(tempFile.toString());
                        tempFile.delete();
                    } else {
                        tempFile.delete();
                    }
                }
            } else {
                deleteMatchingFile.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void wipeDirectory(String name) {
        File directoryFile = new File(name);
        File[] filenames = directoryFile.listFiles();
        if (filenames != null && filenames.length > 0) {
            for (File tempFile : filenames) {
                if (tempFile.isDirectory()) {
                    wipeDirectory(tempFile.toString());
                    tempFile.delete();
                } else {
                    tempFile.delete();
                }
            }
        } else {
            directoryFile.delete();
        }
    }
	
	public void SetButtonLeftPanelImage(int id)
	{
		btnUndo.setBackgroundResource(R.drawable.restore_basic);
		btnLeft.setBackgroundResource(R.drawable.left_swirling_basic);
		btnRight.setBackgroundResource(R.drawable.right_swirling_basic);
		btnMaxi.setBackgroundResource(R.drawable.push_basic);
		btnMini.setBackgroundResource(R.drawable.pinch_basic);
		btnMove.setBackgroundResource(R.drawable.grab_basic);
		//5 2 3 1 0 4
		switch(id)
		{
			case 5:
				btnUndo.setBackgroundResource(R.drawable.restore_on_basic);
				break;
			case 2:
				btnLeft.setBackgroundResource(R.drawable.left_swirling_on_basic);
				break;
			case 3:
				btnRight.setBackgroundResource(R.drawable.right_swirling_on_basic);
				break;
			case 1:
				btnMaxi.setBackgroundResource(R.drawable.push_on_basic);
				break;
			case 0:
				btnMini.setBackgroundResource(R.drawable.pinch_on_basic);
				break;
			case 4:
				btnMove.setBackgroundResource(R.drawable.grab_on_basic);
				break;
		}
	}
	public void SetButtonSizeImage(int id)
	{
		btnSizeHig.setBackgroundResource(R.drawable.size01_off_basic);
		btnSizeMed.setBackgroundResource(R.drawable.size02_off_basic);
		btnSizeLow.setBackgroundResource(R.drawable.size03_off_basic);
		switch(id)
		{
			case 1:
				btnSizeHig.setBackgroundResource(R.drawable.size01_on_basic);
				break;
			case 2:
				btnSizeMed.setBackgroundResource(R.drawable.size02_on_basic);
				break;
			case 3:
				btnSizeLow.setBackgroundResource(R.drawable.size03_on_basic);
				break;				
		}
	}
	public void SetButtonForceImage(int id)
	{
		btnStrenghtHig.setBackgroundResource(R.drawable.force1_off_basic);
		btnStrenghtMed.setBackgroundResource(R.drawable.force2_off_basic);
		btnStrenghtLow.setBackgroundResource(R.drawable.force3_off_basic);
		switch(id)
		{
			case 1:
				btnStrenghtHig.setBackgroundResource(R.drawable.force1_on_basic);
				break;
			case 2:
				btnStrenghtMed.setBackgroundResource(R.drawable.force2_on_basic);
				break;
			case 3:
				btnStrenghtLow.setBackgroundResource(R.drawable.force3_on_basic);
				break;
		}
	}

	public boolean onTouch(View v, MotionEvent event) {
		final View view = v;
		final MotionEvent even = event;
		switch (v.getId()) {
		case R.id.draw:
			handler.post(new Runnable() {
				public void run() {
					panelLeft.getTouchListener().onTouch(view, even);
					panelBottom.getTouchListener().onTouch(view, even);
				}
			});
			break;
		case R.id.setting:

			handler.post(new Runnable() {
				public void run() {
					panelRight.getTouchListener().onTouch(view, even);
				}
			});
			break;

		default:
			break;
		}
		return false;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		return true;
	}
	
	public void Action(View view)
	{
		int kindAction = transform.getActive_kindID();
		//Test =========================================================================================			
		Drawable imgDrawable = ((ImageView) view).getDrawable();
		Bitmap bitmap = ((BitmapDrawable) imgDrawable).getBitmap();
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		
		// Set param
		int area = transform.GetArea() * width / 100;
		int intensity = transform.GetIntensity();
		
		Bitmap edit = bitmap.copy(Bitmap.Config.ARGB_8888, true);
		
		//-------------------------------------------------------------------------
		//action:
		//		0. Pinch (Sphere in)
		// 		1. Push	 (Sphere out)
		// 		2. Left swirl
		//		3. Right swirl
		// 		4. Grab
		// 		5. Undo
		// doan nay goi thuc hien action 3 spherein
		NativeBridge nativeobj = NativeBridge.getInstance();
		float[] matrixX = transform.TransformMatrixX();
		float[] matrixY = transform.TransformMatrixY();
		switch (kindAction)
		{
			case 4:
				//nativeobj.applyWarp1(originbmp, edit, kindAction, matrixX, matrixY, area, intensity, cur_X, cur_Y, pre_X, pre_Y);
				nativeobj.applyWarp1(originbmp, edit, kindAction, matrixX, matrixY, area, intensity, pre_X, pre_Y, cur_X, cur_Y);
				break;
			default:
				nativeobj.applyWarp1(originbmp, edit, kindAction, matrixX, matrixY, area, intensity, cur_X, cur_Y, cur_X, cur_Y);
				break;
		}
		((ImageView)view).setImageBitmap(edit);
		//=================================================================================================
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
//		Toast.makeText(getApplicationContext(),
//				event.getX() + ";" + event.getY(), Toast.LENGTH_SHORT).show();
		return super.onTouchEvent(event);

	}

	OnTouchListener imgSourceOnTouchListener = new OnTouchListener() {

		public boolean onTouch(View view, MotionEvent event) {

			float eventX = event.getX();
			float eventY = event.getY();
			float[] eventXY = new float[] { eventX, eventY };

			Matrix invertMatrix = new Matrix();
			((ImageView) view).getImageMatrix().invert(invertMatrix);

			invertMatrix.mapPoints(eventXY);
			int x = Integer.valueOf((int) eventXY[0]);
			int y = Integer.valueOf((int) eventXY[1]);
			
			if (x < 0 || y < 0) {
				textView.setText("out");
				return true;
			}
			
			//============================================================================================
			// event handle
			int eventaction = event.getAction();
			cur_X = x;
			cur_Y = y;
		    switch (eventaction) {
		        case MotionEvent.ACTION_DOWN: 
		            // finger touches the screen
		        	if(isPressing == true)
		        	{
		        		long now = System.nanoTime();
		        		float seconds = (now - pre_time) / 1000000000.0f;//for seconds
		        		if(seconds > eslaspe_time)
		        		{
		        			pre_time = now;
		        			// some process
		        			
		        			pre_X = cur_X;
		        			pre_Y = cur_Y;
		        			
		        			// perform warp
			        		//Action(view);
		        		}

		        	}
		        	else
		        	{
		        		isPressing = true;
		        		pre_X = cur_X = x;
		        		pre_Y = cur_Y = y;
		        		pre_time = System.nanoTime();
		        		
		        		// perform warp
		        		Action(view);
		        	}
		            break;

		        case MotionEvent.ACTION_MOVE:
		            // finger moves on the screen
		        	if(isPressing == true)
		        	{
		        		long now = System.nanoTime();
		        		float seconds = (now - pre_time) / 1000000000.0f;//for seconds
		        		if(seconds > eslaspe_time)
		        		{		        			
		        			// perform warp
			        		Action(view);
			        		
		        			pre_time = now;
		        			// some process
		        			
		        			pre_X = cur_X;
		        			pre_Y = cur_Y;

		        		}
		        	}
		            break;

		        case MotionEvent.ACTION_UP:   
		            // finger leaves the screen
		        	isPressing = false;
		        	
	        		// perform warp
	        		Action(view);

        			pre_X = cur_X;
        			pre_Y = cur_Y;

		            break;
		    }
		    //=============================================================================================
			
			/*// Test =========================================================================================			
			Drawable imgDrawable = ((ImageView) view).getDrawable();
			Bitmap bitmap = ((BitmapDrawable) imgDrawable).getBitmap();
			int width = bitmap.getWidth();
			int height = bitmap.getHeight();
			
			// Set param
			transform.setActive_kindID(1);
			int area = transform.GetArea() * width / 100;
			int intensity = transform.GetIntensity();
			
			Bitmap edit = bitmap.copy(Bitmap.Config.ARGB_8888, true);
			
			textView.setText(x + ";" + y);
			
			//-------------------------------------------------------------------------
			//action:
			//		0. Pinch (Sphere in)
			// 		1. Push	 (Sphere out)
			// 		2. Left swirl
			//		3. Right swirl
			// 		4. Grab
			// 		5. Undo
			// doan nay goi thuc hien action 3 spherein
			NativeBridge nativeobj = NativeBridge.getInstance();
			float[] matrixX = transform.TransformMatrixX();
			float[] matrixY = transform.TransformMatrixY();
			nativeobj.applyWarp1(originbmp, edit, 1, matrixX, matrixY, area, intensity, x, y, x + 40, y + 40);
			((ImageView)view).setImageBitmap(edit);
			//=================================================================================================
			int touchedRGB = bitmap.getPixel(x, y);*/
			
			
			return true;
		}
	};

}
